function _Board (width, height, table, playerFirst) {

	let size = width * height;
	let _board = new Array(size).fill(0);
	let step = 1;
	let counts = [ 5, 125, 3125, 625, 25 ];

	function where(x, y) {
		return y * width + x;
	}

	function put (x, y) {

		let now = where(x, y);

		if (!isEmpty(x, y)) return;

		_board[now] = counts[0];

		let td = table[now];
		let div = document.createElement("div");
		let isOdd = step % 2 !== 0;
		div.className = "go " + (isOdd ? "go_black" : "go_white");
		td.appendChild(div);
		step++;

		let isPlayer = (isOdd && playerFirst) || (!isOdd && !playerFirst); // 奇数步 + 先手 或者 偶数步 + 后手
		_board[now] = isPlayer ? 1 : -1;

		if (isPlayer) {
			aiPut();
		}
	}

	function aiPut () {
		let bestPosition = calcBestPosition();

		if (bestPosition === -1) return; // 不再有空位时（最后一个格子）停止搜索

		let xy = getXY(bestPosition);
		if (isEmpty(xy.x, xy.y)) {
			put(xy.x, xy.y);
		} else {
			aiPut(); // 为了避免出现判空失败不落子的情况出现，所以用递归处理
		}
	}

	function isWin() {
		for (let y = 0; y < 10; y++) {
			for (let x = 0; x < 10; x++) {
				// 向右
				let toRight = 0;
				for (let i = 0; i < 5; i++) {
					toRight += _board[where(x + i, y)];
				}
				if (toRight === 5) return true;
				// 向右下
				let toDownRight = 0;
				for (let i = 0; i < 5; i++) {
					toDownRight += _board[where(x + i, y + i)];
				}
				if (toDownRight === 5) return true;
				// 向下
				let toDown = 0;
				for (let i = 0; i < 5; i++) {
					toDown += _board[where(x, y + i)];
				}
				if (toDown === 5) return true;
			}
		}

		return false;
	}

	// 这里是 AI 的算法
	function calcBestPosition () {

		let empty = [];

		// TODO 临时采用随机数产生位置
		for (let i = 0; i < size; i++) {
			if (_board[i] === 0) {
				empty.push(i);
			}
		}

		if (empty.length === 0) {
			return -1;
		}

		let index = Math.trunc(Math.random() * empty.length);
		return empty[index];
	}

	function getXY (position) {
		let x = position % height;
		let y = (position - x) / height;

		return {
			x, y
		}
	}

	function isEmpty (x, y) {
		let index = where(x, y);
		return _board[index] === 0;
	}

	return {
		getXY,
		put,
		isEmpty,
		isWin,
		getSize: () => {
			return size;
		}
	}
}

function pressEvent(width, height, table, playerFirst) {

	const board = _Board(width, height, table, playerFirst);

	if (!playerFirst) {
		let position = Math.trunc(Math.random() * board.getSize());
		let xy = board.getXY(position);
		board.put(xy.x, xy.y);
	}

	return {
		left: board.put,
		isWin () {
			if (board.isWin()) {
				showResult("赢", width, height, playerFirst);
			}
		}
	};
}